home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / clock.aqm / clock.asm
Assembly Source File  |  1985-01-28  |  17KB  |  683 lines

  1. PAGE 60,132
  2. TITLE Replacement system clock driver for AST board
  3. COMMENT*This is an installable device driver to access the battery
  4.     driven clock on AST combo board & I/O port 2C0+1F
  5.  
  6.     AUTHOR: David K.Broadwell -- July 1983
  7.  
  8.     Copied from BYTE 1/84 by Fred A. Strobl -- Jan. 84
  9.     REVISED TO ELIMINATE 12K OF WASTED MEMORY - ADDED SET DAY OF WEEK
  10.     TO INSTALL: ADD TO CONFIG.SYS :
  11.             DEVICE=CLOCK.COM
  12.  
  13.     Daniel M. O'Brien (dmo) - 1/28/84
  14.      Set the bios time counter (tics) from clock chip for those applications
  15.      that read the bios counter directly (via INT 1A)!
  16.  
  17.     *
  18.  
  19. CSEG   SEGMENT PARA PUBLIC 'CODE'
  20.  
  21. ;
  22. ;    M A C R O S
  23. ;
  24. STATUS    MACRO    STATE,ERR,RC
  25.     ifidn    <STATE>,<DONE>
  26.     OR    ES:WORD PTR SRH_STA_FLD[BX],0100H
  27.     endif
  28.     ifidn    <STATE>,<BUSY>
  29.     OR    ES:WORD PTR SRH_STA_FLD[BX],0200H
  30.     endif
  31.     ifidn    <ERR>,<ERROR>
  32.     OR    ES:WORD PTR SRH_STA_FLD[BX],1000H
  33.     endif
  34.     ifnb    <RC>
  35.     OR    ES:WORD PTR SRH_STA_FLD[BX],RC
  36.     endif
  37.     endm
  38.  
  39. ;
  40. ;    E Q U A T E S
  41. ;
  42. SRH        EQU    0            ;STATIC REQUEST HEADER START
  43. SRH_LEN     EQU    13            ;   "      "      "    LENGTH
  44. SRH_LEN_FLD    EQU    SRH            ;   "      "      "      "   FIELD
  45. SRH_UCD_FLD    EQU    SRH+1            ;SRH UNIT CODE FIELD
  46. SRH_CCD_FLD    EQU    SRH+2            ;SRH COMMAND CODE FIELD
  47. SRH_STA_FLD    EQU    SRH+3            ;SRH STATUS FIELD
  48. SRH_RES_FLD    EQU    SRH+5            ;SRH RESERVED AREA FIELD
  49.  
  50. ;
  51. ; INPUT OR OUTPUT
  52. ;
  53. BUF        EQU    14            ;OFFSET INTO THE REQ BLOCK OF DATA (BUFFER) TRANSFER ADDRESS
  54. BUF_LEN     EQU    4            ;BUF LENGTH
  55.  
  56. ;
  57. ; INIT
  58. ;
  59. BR_ADDR_0    EQU    14            ;CHARACTER DEVICE USUALLY ONLY SETS
  60. BR_ADDR_1    EQU    BR_ADDR_0+2        ; ENDING ADDRESS AND RETURNS
  61. BR_ADDR_LEN    EQU    4
  62.  
  63. ;
  64. ; OFFSETS FROM CLOCK BASE PORT
  65. ;
  66. MON        EQU    7            ;OFFSET OF MONTH
  67. DAYY        EQU    6            ;   "   "  DAY OF MONTH
  68. VALID        EQU    8            ;   "   "  VALIDATION CODE IN RAM
  69. MON_CHECK    EQU    9            ;   "   "  MONTH CHECKER IN RAM
  70. SWITCH        EQU    0BH            ;   "   "  LEAP BK RAM ON CHIP
  71. COUNTER_RESET    EQU    12H            ;   "   "  OF RESET(RAM RESET IS ONE UP AT 13H)
  72. STATUS_BIT    EQU    14H            ;OFFSET TO STATUS BYTE--80=UNRELIABLE READ, 00 = OK
  73.  
  74. ;
  75. ; MISC
  76. ;
  77. DAYS_YR     EQU    365            ;DAYS PER USUAL YEAR
  78. YES_CODE    EQU    02            ;YES CODE FOR LEAP YEAR BOOKEEPING
  79. NO_CODE     EQU    01            ;NO CODE FOR SAME
  80. VALID_CODE    EQU    10H            ;VALIDATE CHIP CODE
  81. DAYS_FEB29    EQU    60            ;DAYS UP TO AND INCLUDING FEB 29TH (FOR LEAP YEARS ONLY)
  82.  
  83. ;
  84. ; S T R U C T U R E S
  85. ;
  86. CLOCK        EQU    2C0H            ;BASE PORT
  87.  
  88. ;
  89. ; ■■ 58157A CLOCK-CALENDAR CHIP I/O ADDRESSES
  90. ;
  91. CLOCK_PORTS    STRUC
  92. TEN_THOUS    DB    ?            ;1/10000s of seconds(who cares?)
  93. HUNDS        DB    ?            ;hundredth
  94. SECS        DB    ?            ;seconds
  95. MINS        DB    ?            ;minutes
  96. HRS        DB    ?            ;hours
  97. WEK_DAY     DB    ?            ;day of week
  98. DAY        DB    ?            ;day of month
  99. MO        DB    ?            ;month
  100. VERIFY        DB    ?            ;chip RAM used to check chip config at initialization
  101. MON_CHK     DB    ?            ;RAM with month of last chip access
  102. YR        DB    ?            ;year-1980 (port 2C0 + 0A)
  103. LEAP_BK     DB    ?            ;used for leap year bookeeping (set to 02 when all is cool)
  104. ;
  105. CLOCK_PORTS    ENDS
  106.  
  107. CLK    PROC    FAR
  108.     ASSUME    CS:CSEG,ES:CSEG,DS:CSEG
  109. BEGIN:
  110.  
  111. ;
  112. ;    S P E C I A L    D E V I C E    H E A D E R
  113. ;
  114. NEXT_DEV    DD    -1            ;POINTER TO NEXT DEVICE
  115. ATTRIBUTE    DW    8008H            ;CLOCK DEVICE (NEW STD.)
  116. STRATEGY    DW    DEV_STRATEGY        ;POINTER TO DEVICE STRATEGY
  117. INTERRUPT    DW    DEV_INT         ;POINTER TO INTERRUPT HANDLER
  118. DEV_NAME    DB    'CLOCK$'                ;DEVICE NAME
  119.         DB    2 DUP(?)        ;FILLER
  120. ;
  121. RH_OFF        DW    ?            ;REQUEST HEADER OFFSET
  122. RH_SEG        DW    ?            ;R HDR SEGMENT
  123. USER_BUF    DD    ?            ;USER TRANSFER ADDRESS (BUFFER)
  124.  
  125. ;
  126. ;    FUNCTION TABLE
  127. ;
  128. FUNTAB    LABEL    BYTE
  129.     DW    INIT        ;INITIALIZATION -USED FIRST TIME DEVICE IS CALLED
  130.     DW    MEDIA_CHECK    ;(BLOCK ONLY)    -NOT USED
  131.     DW    BUILD_BPB    ;    "    "     -NOT USED
  132.     DW    IOCTL_IN    ;IOCTL INPUT    -NOT USED
  133.     DW    INPUT        ;INPUT(READ) = GET THE TIME/DATE
  134.     DW    ND_INPUT    ;NON-DESTRUCTIVE INPUT (CHAR ONLY) -NOT USED
  135.     DW    IN_STAT     ;CHAR ONLY    -NOT USED
  136.     DW    IN_FLUSH    ;C.O        -NOT USED
  137.     DW    OUTPUT        ;OUTPUT(WRITE) = SET TIME/DATE
  138.     DW    OUT_VERIFY    ;OUTPUT W/VERIFY-NOT USED
  139.     DW    OUT_STAT    ;C.O.        -NOT USED
  140.     DW    OUT_FLUSH    ;C.O.        -NOT USED
  141.     DW    IOCTL_OUT    ;IOCTL OUTPUT    -NOT USED
  142.  
  143. ;
  144. ;    LOCAL DATA BLOCK IN DOS 2.0 FORMAT
  145. ;
  146. CLK_TBL LABEL    BYTE
  147.     DW    ?        ;DAYS SINCE 1-1-80
  148.     DB    ?        ;MINS
  149.     DB    ?        ;HOURS
  150.     DB    ?        ;1/100THS SEC
  151.     DB    ?        ;SECONDS
  152.  
  153. ;
  154. ;    MONTH TABLE
  155. ;
  156. MON_TBL LABEL    BYTE
  157.     DW    0        ;JAN
  158.     DW    31        ;FEB
  159.     DW    59        ;MAR
  160.     DW    90        ;APR
  161.     DW    120        ;MAY
  162.     DW    151        ;JUNE
  163.     DW    181        ;JULY
  164.     DW    212        ;AUG
  165.     DW    243        ;SEPT
  166.     DW    273        ;OCT
  167.     DW    304        ;NOV
  168.     DW    334        ;334 DAYS UP TO DEC 1
  169.     DW    365        ;DAYS UP TO JAN 1, NEXT YR
  170.  
  171. ;
  172. ;    TABLE OF CURRENT CLOCK VALUES
  173. ;
  174. UHR    CLOCK_PORTS    <>    ;Allocates to predefined STRUC
  175.  
  176. ;
  177. ;    VARIABLES FOR TRACKING THOSE PESKY LEAP YEARS
  178. ;
  179. LEAP_STAT    DB    0    ;10H MEANS CURRENT YEAR IS A LEAP
  180. NUM_LEAPS    DB    ?    ;NUMBER OF LEAP YEARS SINCE 1980
  181.  
  182. ;
  183. ;   L O C A L    P R O C E D U R E S
  184. ;
  185. IN_SAVE PROC    NEAR
  186.     MOV    AX,ES:WORD PTR BUF[BX]    ;SAVE CALLER'S BUFFER ADD
  187.     MOV    CS:USER_BUF,AX
  188.     MOV    AX,ES:WORD PTR BUF+2[BX]
  189.     MOV    CS:USER_BUF+2,AX
  190.     RET
  191. IN_SAVE ENDP
  192.  
  193.  
  194. READ_CLOCK    PROC    NEAR
  195.  
  196.     call    read_chip    ;read time off chip into uhr structure         dmo
  197. ;
  198. ;   Routine to massage data for transfer to DOS
  199. ;
  200.     CALL    NEW_YEAR        ;CHECK TO SEE IF IT'S A NEW YEAR
  201.     CALL    DAYS            ;NUMBER OF DAYS SINCE 1/1/80
  202.     CALL    TIME            ;CURRENT TIME IN HEX
  203.  
  204.     MOV    ES,CS:USER_BUF+2    ;SET DESTINATION (ES:DI) TO POINT TO
  205.     MOV    DI,CS:USER_BUF        ; CALLER'S BUFFER
  206.     PUSH    CS
  207.     POP    DS            ;ESTABLISH SOURCE
  208.                     ;SI ALREADY HAS CLK_TBL ADDRESS
  209.     MOV    CX,6            ;6 BYTES
  210.     REP    MOVSB            ;SEND INFO TO BUFFER FOR "READ"
  211.     RET
  212. READ_CLOCK    ENDP
  213.  
  214. ;
  215. ; read time off chip into uhr data structure - made a subroutine by -------> dmo
  216. ;
  217. read_chip    proc    near
  218.     PUSH    CS        ;SET UP TO READ CHIP AND STORE IT
  219.     POP    ES
  220. RETRY:    LEA    DI,UHR
  221.     CLD
  222.     SUB    AX,AX
  223.     MOV    CX,12
  224.     MOV    DX,CLOCK    ;ADDRESS OF CHIP BASE PORT
  225. LOADIT: IN    AL,DX
  226.     INC    DX
  227.     PUSH    CX
  228.     CALL    DEC_HEX     ;CONVERT BCD TO HEX
  229.     STOSB
  230.     POP    CX        ;RESTORE COUNTER
  231.     LOOP    LOADIT
  232.  
  233. ;
  234. ;   Check for counter rollover during read (STATUS BYTE = 80H)
  235. ;
  236.     MOV    DX,CLOCK+STATUS_BIT
  237.     IN    AL,DX
  238.     TEST    AL,AL
  239.     JNZ    RETRY
  240.     ret            ;                         dmo
  241. read_chip    endp        ;                         dmo
  242.  
  243. DAYS    PROC    NEAR
  244.     SUB    AX,AX
  245.     MOV    AL,UHR.YR        ;YEAR-1980
  246.     MOV    BX,DAYS_YR
  247.     MUL    BX            ;MUL FOR DAYS
  248.     SUB    CX,CX
  249.     MOV    CL,UHR.MO        ;LOAD MONTH IN CL AND ...
  250.     CALL    DAYS_MONTH        ; CALL ROUTINE TO ACCESS MONTH TABLE
  251.     ADD    AX,WORD PTR[BX]     ;ADD THAT YEAR'S DAYS (XCEPT CUR MO)
  252.     XOR    BH,BH
  253.     MOV    BL,UHR.DAY        ;GET DAY OF MONTH
  254.     ADD    AX,BX            ;DAYS SINCE 1-1-80,EXCEPT LEAP DAYS
  255.     PUSH    AX
  256.     MOV    AL,UHR.YR
  257.     CALL    LEAP_CHK        ;CHECK THOSE TOO
  258.     POP    AX
  259.     SUB    DX,DX
  260.     MOV    DL,NUM_LEAPS
  261.     ADD    AX,DX            ;ADD IN OLD LEAP DAYS
  262.     TEST    LEAP_STAT,10H        ;CURRENT YEAR A LEAP?
  263.     JZ    D1            ;JUMP ON NO
  264.     CALL    LEAP_ADJ        ;YES -GO FIX THINGS
  265. D1:    LEA    SI,CLK_TBL
  266.     MOV    WORD PTR [SI],AX    ;SAVE RESULT
  267.     RET
  268. DAYS    ENDP
  269.  
  270. ;
  271. ;     GET HRS,MIN,SEC AND 1/100THS SEC
  272. ;
  273. TIME    PROC    NEAR
  274.     LEA    DI,CLK_TBL[2]        ;SET UP TO LOAD DATA LOCALLY IN RIGHT ORDER
  275.     XOR    AH,AH
  276.     MOV    AL,UHR.MINS
  277.     STOSB
  278.     MOV    AL,UHR.HRS
  279.     STOSB
  280.     MOV    AL,UHR.HUNDS
  281.     STOSB
  282.     MOV    AL,UHR.SECS
  283.     STOSB
  284.     RET
  285. TIME    ENDP
  286.  
  287. DAYS_MONTH    PROC    NEAR        ;MONTH ARRIVES HERE IN CL
  288.     SUB    CL,1            ;ADJUST TO GET THE CORRECT OFFSET INTO
  289.     ROL    CL,1            ;  THE TABLE
  290.     LEA    BX,MON_TBL        ;GET ADDRSS OF MONTH TABLE
  291.     ADD    BX,CX            ;NOW WORD PTR[BX] HAS NUM OF DAYS UP TO THE CURRENT MO
  292.     RET
  293. DAYS_MONTH    ENDP
  294.  
  295. NEW_YEAR    PROC    NEAR        ;CHECK FOR A "NEW YEAR" AND/OR UPDATE MON_CHK
  296.     MOV    AL,UHR.MO        ;CURRENT MONTH
  297.     CMP    AL,UHR.MON_CHK        ;STORED ON CHIP - THE LAST "MONTH" WE READ IT
  298.     JL    NEW            ;1<12 SO IT'S A NEW YEAR
  299.     JG    UPDATE            ; IT'S A NEW MONTH
  300.     RET                ;SAME OLD MONTH - GO BACK
  301. NEW:    INC    UHR.YR            ;LAST YEAR - 1980,+1
  302.     MOV    AL,UHR.YR
  303.     CALL    HEX_DEC         ;MAKE IT BCD LIKE EVERYTHING ELSE
  304.     MOV    DX,CLOCK+10        ;RAM ADD FOR YEAR
  305.     OUT    DX,AL
  306. UPDATE: MOV    AL,UHR.MO        ;UPDATE MON_CHK ON RAM
  307.     MOV    DX,CLOCK+9
  308.     OUT    DX,AL
  309.     RET
  310. NEW_YEAR    ENDP
  311.  
  312. DEC_HEX PROC    NEAR            ;CONVERTS SMALL PACKED BCD TO HEX
  313.     PUSH    AX
  314.     MOV    CL,4
  315.     SHR    AL,CL
  316.     POP    BX
  317.     MOV    BH,10
  318.     MUL    BH
  319.     AND    BL,0FH
  320.     ADD    AL,BL
  321.     RET
  322. DEC_HEX ENDP
  323.  
  324. HEX_DEC PROC    NEAR            ;CONVERTS HEX NUMBERS UP TO 63H(=99) TO BCD
  325.     SUB    AH,AH            ; HEX NUMBER PASSED IN AL
  326.     MOV    BL,10
  327.     DIV    BL
  328.     MOV    CL,04
  329.     SHL    AL,CL
  330.     XCHG    AL,AH
  331.     OR    AL,AH            ;BCD IN AL
  332.     RET
  333. HEX_DEC ENDP
  334.  
  335. LEAP_CHK    PROC    NEAR        ;SETS NUMBER OF LEAP YEARS PAST &
  336. STATUS    BYTE
  337.     CMP    AL,0            ;IS IT 1980 ?
  338.     JE    L2            ;YES - FORGET THE REST
  339.     XOR    AH,AH            ;PUT YEAR-1980 IN AL BEFORE CALL
  340.     DEC    AL
  341.     MOV    BL,4
  342.     DIV    BL
  343.     CMP    AH,3
  344.     JNE    NOT_LEAP
  345.     OR    LEAP_STAT,10H        ;SET LEAP STATUS BIT ON(CURR YR IS A LEAP)
  346.     JMP    L1
  347. NOT_LEAP:
  348.     MOV    LEAP_STAT,0
  349. L1:    MOV    NUM_LEAPS,AL        ;NUMBER OF LEAP DAYS SINCE 1980
  350. L2:    RET
  351. LEAP_CHK    ENDP
  352.  
  353. LEAP_ADJ    PROC    NEAR        ;ADJUSTS CHIP AND/OR DAYS COUNT DURING LEAPS
  354.     CMP    UHR.LEAP_BK,YES_CODE    ;HAVE WE ALREADY DONE THE BOOKEEPING?
  355.     JE    DONE1            ;JUMP ON YES
  356.     MOV    BH,UHR.MO        ;IS IT BEFORE/AT FEB 29 -- (CHIP THINKS IT'S 3/1)
  357.     MOV    BL,UHR.DAY
  358.     CMP    BX,0301H
  359.     JLE    DONE2            ;YES - JUMP
  360. ;
  361. ;BACK UP A DAY AND RECORD IT IN RAM:
  362. ;
  363.     CMP    UHR.DAY,1        ;IS IT THE 1ST OF A MONTH?
  364.     JE    FOOEY            ;JUMP ON YES AND WHAT A PAIN
  365.     PUSH    AX            ;NO -JUST BACK UP ONE DAY AND SET LEAP_BK
  366.     XOR    AH,AH
  367.     MOV    AL,UHR.DAY
  368.     DEC    AL
  369. BAK:    MOV    DX,CLOCK+DAYY        ;CHIP PORT
  370.     OUT    DX,AL
  371.     MOV    AL,YES_CODE
  372.     MOV    DX,CLOCK+SWITCH
  373.     OUT    DX,AL            ;SET LEAP_BK ON RAM SO WE WON'T HAVE TO DO THIS AGAIN
  374.     POP    AX
  375.     JMP    DONE2
  376.  
  377. FOOEY:    SUB    CX,CX            ;BACK UP DAY AND MONTH BOTH
  378.     MOV    CL,UHR.MO
  379.     PUSH    AX
  380.     MOV    AX,CX
  381.     MOV    DX,CLOCK+MON
  382.     DEC    AL
  383.     OUT    DX,AL
  384.     ADD    DX,2            ;RESET MONTH VERIFY ON RAM TOO
  385.     OUT    DX,AL
  386.     CALL    DAYS_MONTH
  387.     MOV    AX,WORD PTR[BX]     ;NOW FIND OUT HOW MANY DAYS LAST MONTH    HAD
  388.     SUB    AX,WORD PTR[BX]-2    ;YESTERDAY NOW IN AL
  389.     JMP    BAK            ;FINISH UP
  390.  
  391. DONE1:    INC    AX            ;ALL THE REST OF YR ADD ONE MO' DAY
  392. DONE2:    RET
  393. LEAP_ADJ    ENDP
  394.  
  395. SET_CLOCK    PROC    NEAR        ;GETS DATA FROM DOS, CRUNCHES IT & SETS CHIP
  396.     MOV    DS,CS:USER_BUF+2    ;SET SOURCE TO CALLER'S(DOS)BUFFER BLK ADR
  397.     MOV    SI,CS:USER_BUF
  398.     PUSH    CS
  399.     POP    ES
  400.     LEA    DI,CLK_TBL
  401.     MOV    CX,6            ;SET UP TO MOVE DATA LOCALLY
  402.     CLD
  403.     REP    MOVSB            ;DO IT
  404.  
  405. ;
  406. ; CALCULATE AND LOAD LOCAL CLOCK CHIP TABLE (STRUCTURE)
  407. ;
  408.     PUSH    CS
  409.     POP    DS            ;ESTABLISH DS AS THIS SEG
  410.     CALL    LOAD_TICKS        ;DO TIME PART(EASY)
  411.     CALL    UNSCRAM         ;DAYS TO YR-MO-DAY
  412.  
  413. ;
  414. ;    SET CHIP
  415. ;
  416.     SUB    AX,AX
  417.     MOV    CX,12
  418.     MOV    DX,CLOCK        ;CHIP BASE PORT ADDRESS
  419.     LEA    SI,UHR            ;SOURCE=CHIP TABLE WE'VE SET UP
  420. DMPIT:    LODSB                ;MOVE DATA TO AL
  421.     PUSH    CX            ;NEXT ROUTINE TRASHES COUNTER
  422.     CALL    HEX_DEC         ;CHANGE TO BCD
  423.     OUT    DX,AL            ;"WRITE" TO CHIP
  424.     INC    DX            ;NEXT PORT
  425.     POP    CX
  426.     LOOP    DMPIT            ;LOOP 'TIL DONE
  427.     RET
  428. SET_CLOCK    ENDP
  429.  
  430. LOAD_TICKS    PROC    NEAR        ;LOAD TIME INTO CHIP STRUCTURE FORMAT
  431.     LEA    SI,CLK_TBL[2]
  432.     XOR    AH,AH
  433.     LODSB
  434.     MOV    UHR.MINS,AL
  435.     LODSB
  436.     MOV    UHR.HRS,AL
  437.     LODSB
  438.     MOV    UHR.HUNDS,AL
  439.     LODSB
  440.     MOV    UHR.SECS,AL
  441.     RET
  442. LOAD_TICKS    ENDP
  443.  
  444. UNSCRAM PROC    NEAR            ;DAYS SINCE 1-1-80 TO MM/DD/YY
  445.     LEA    BP,CLK_TBL
  446.     MOV    AX,WORD PTR CS:[BP]    ;FIRST WORD IN CLK_TBL
  447.     CMP    AX,0            ;IF IT'S 1-1-80, TAKE SHORT CUT
  448.     JE    U4
  449. ;ADDED DAY OF WEEK ROUTINE *** FAS
  450.     PUSH    AX            ;            ***FAS
  451.     ADD    AX,3            ;1-1-1980=TUESDAY(DAY3) ***FAS
  452.  
  453.     CWD                ;            ***FAS
  454.     MOV    BX,7            ;DAYS IN WEEK        ***FAS
  455.     DIV    BX            ;            ***FAS
  456.     MOV    UHR.WEK_DAY,DL        ;STORE            ***FAS
  457.     POP    AX            ;CONTINUE        ***FAS
  458.     MOV    BX,DAYS_YR
  459.     CWD                ;BLANK OUT DX FOR DIVIDE
  460.     DIV    BX            ;YRS GOTO AL,DAYS LEFT TO DX
  461.     MOV    UHR.YR,AL        ;SAVE YRS SINCE 1980
  462.                     ;NOW CHECK WHETHER LEAP DAYS OR END OF
  463.     CALL    LEAP_CHK        ;    YEAR HAVE MADE IT LOOK LIKE A NEW YR
  464.     SUB    CX,CX
  465.     MOV    CL,NUM_LEAPS
  466.     CMP    DX,CX
  467.     JG    OK            ;IF REMAINDER DAYS<LEAP DAYS, FIX IT
  468.     ADD    DX,DAYS_YR
  469.     DEC    UHR.YR            ;ALL FILLED NOW
  470.     MOV    AL,UHR.YR        ;REDO LEAP VARIABLES
  471.     CALL    LEAP_CHK
  472. OK:    XOR    BX,BX
  473.     MOV    BL,NUM_LEAPS
  474.     SUB    DX,BX            ;CORRECT FOR LEAPS
  475.     TEST    LEAP_STAT,10H        ;CURRENT YEAR A LEAP ?
  476.     JZ    U0            ;JUMP ON NO
  477.     CMP    DX,DAYS_FEB29        ;AT/BEFORE FEB 29?
  478.     JLE    U0            ;YES- JUMP
  479.     MOV    UHR.LEAP_BK,YES_CODE    ;SET RAM SWITCH TO 'YES'
  480.     DEC    DX            ;NO - TAKE OUT THAT EXTRA DAY
  481.     JMP    U1
  482. U0:    MOV    UHR.LEAP_BK,NO_CODE    ;SET RAM TO 'NO'
  483. U1:    MOV    BX,26
  484.     LEA    DI,MON_TBL
  485. U2:    SUB    BX,2
  486.     CMP    WORD PTR [DI][BX],DX
  487.     JGE    U2            ;FIND RIGHT MONTH IN TABLE
  488.     SUB    DX,WORD PTR [DI][BX]    ;DAYS INTO MONTH LEFT IN DX
  489.     ROR    BL,1
  490.     INC    BL
  491. U3:    MOV    UHR.DAY,DL
  492.     MOV    UHR.MON_CHK,BL        ;SET UP MONTH VERIFY IN RAM TOO
  493.     MOV    UHR.MO,BL
  494.     RET
  495. U4:    MOV    DL,0            ;SET UP FOR 1-1-80 "in the beginning..."
  496.     MOV    BL,1
  497.     MOV    UHR.YR,0
  498.     JMP    U3
  499. UNSCRAM ENDP
  500.  
  501. ;                                         dmo
  502. ; setup bios ram counter - tics (18.2/sec) since midnight             dmo
  503. ;                                         dmo
  504. ; called whenever chip is changed and during initialization             dmo
  505. ;                                         dmo
  506. ;                                         dmo
  507. set_bios_counter    proc    near
  508.     push    cs
  509.     pop    ds    ;setup data addressability
  510.  
  511.     xor    ah,ah
  512.     mov    al,uhr.hrs    ;get current hours
  513.     mov    cx,60        ;convert to minutes
  514.     mul    cx
  515.     mov    bx,ax        ;save for total
  516.  
  517.     xor    ah,ah
  518.     mov    al,uhr.mins    ;get current minutes
  519.     add    ax,bx        ;total minutes
  520.     mov    cx,1092     ;convert minutes to tics - tech ref a-4
  521.     mul    cx
  522.  
  523.     push    dx        ;save current total tics - high word
  524.     push    ax        ;             - low word
  525.  
  526.     xor    ah,ah
  527.     mov    al,uhr.secs    ;get current seconds
  528.     mov    cx,18        ;convert secs to tics
  529.     mul    cx
  530.  
  531.     pop    cx        ;get previous total tics - low word
  532.     add    ax,cx        ;sum tics
  533.     pop    cx        ;get previous total ticss - high word
  534.     adc    dx,cx        ;sum tics
  535.  
  536.     mov    cx,dx        ;get tics into proper regs
  537.     mov    dx,ax
  538.     mov    ah,1        ;flag to set clock
  539.     int    1ah        ;set clock via bios - tech ref a-77
  540.     ret
  541. set_bios_counter    endp    ;                         dmo
  542.  
  543. ;
  544. ;    D E V I C E    S T R A T E G Y
  545. ;
  546. DEV_STRATEGY:
  547.     MOV    CS:RH_SEG,ES        ;SAVE SEGMENT OF REQUEST HEADER PTR
  548.     MOV    CS:RH_OFF,BX        ;SAVE OFFSET OF SAME
  549.     RET
  550.  
  551. ;
  552. ;   D E V I C E    I N T E R R U P T      H A N D L E R
  553. ;
  554. DEV_INT:
  555. ;PRESERVE MACHINE STATE
  556.     CLD
  557.     PUSH    DS
  558.     PUSH    ES
  559.     PUSH    AX
  560.     PUSH    BX
  561.     PUSH    CX
  562.     PUSH    DX
  563.     PUSH    DI
  564.     PUSH    SI
  565.  
  566. ;
  567. ;BRANCH ACCORDING TO THE FUNCTION PASSED
  568. ;
  569.     MOV    BX,CS:RH_OFF        ;GET REQUEST BLOCK ADDRESS FROM WHERE
  570.     MOV    ES,CS:RH_SEG        ;    DEVICE STRATEGY PUT IT
  571.     MOV    AL,ES:[BX]+2        ;GET FUNCTION BYTE
  572.     ROL    AL,1            ;GET OFFSET INTO TABLE
  573.     LEA    DI,FUNTAB        ;GET ADDRESS OF FUNCTION TABLE
  574.     XOR    AH,AH
  575.     ADD    DI,AX
  576.     JMP    WORD PTR[DI]
  577.  
  578. ;
  579. ; THE FOLLOWING ENTRIES ARE NOT SUPPORTED BY THIS DEVICE
  580. ;
  581. IOCTL_IN:
  582. IOCTL_OUT:
  583. ND_INPUT:
  584. IN_STAT:
  585. IN_FLUSH:
  586. OUT_STAT:
  587. OUT_FLUSH:
  588. MEDIA_CHECK:
  589. BUILD_BPB:
  590. OUT_VERIFY:
  591.     STATUS    DONE,ERROR,03        ;SET STATUS BYTE AS "ERROR-UNK COMMAND"
  592.     JMP    EXIT
  593.  
  594. ;
  595. ;  INPUT = READ THE CLOCK CHIP
  596. ;
  597. INPUT:
  598.     CALL    IN_SAVE         ;CALL THE INITIAL SAVE RTN
  599.     CALL    READ_CLOCK        ;READ IN THAT DATE/TIME
  600.     MOV    BX,CS:RH_OFF        ;RESTORE ES:BX AS REQ HDR PTR
  601.     MOV    ES,CS:RH_SEG
  602.     STATUS    DONE,NOERROR,0
  603.     JMP    EXIT
  604.  
  605. ;
  606. ; OUTPUT = SET TIME & DATE
  607. ;
  608. OUTPUT:
  609.     CALL    IN_SAVE         ;CALL INITIAL SAVE ROUTINE
  610.     CALL    SET_CLOCK        ;SET TIME & DATE
  611.     call    set_bios_counter    ;also set bios time counter        dmo
  612.     MOV    BX,CS:RH_OFF        ;RESTORE ES:BX AS REQ HDR PTR
  613.     MOV    ES,CS:RH_SEG
  614.     STATUS    DONE,NOERROR,0
  615.     JMP    EXIT
  616.  
  617. ;
  618. ; EVERYBODY'S EXIT
  619. ;
  620. EXIT:
  621.     POP    SI
  622.     POP    DI
  623.     POP    DX
  624.     POP    CX
  625.     POP    BX
  626.     POP    AX
  627.     POP    ES
  628.     POP    DS
  629.     RET
  630.  
  631. ;
  632. ;    INIT
  633. ;
  634. INIT:
  635.     PUSH    CS
  636.     POP    AX            ;CURRENT CS TO AX
  637. ;    ADD    AX,OFFSET INIT        ;WRONG OFFSET        ***FAS
  638.     MOV    DX,OFFSET INIT        ;CORRECT OFFSET     ***FAS
  639. ;    MOV    ES:WORD PTR BR_ADDR_0[BX],0    ;WRONG ADD    ***FAS
  640.     MOV    ES:WORD PTR BR_ADDR_0[BX],DX    ;CORRECT ADD    ***FAS
  641.     MOV    ES:BR_ADDR_1[BX],AX    ;MAKE THAT THE BREAK ADDRESS
  642.  
  643. ;
  644. ;CHECK VERIFY BYTE - HAS SOME OTHER SOFTWARE DIDDLED THE CLOCK?
  645. ;
  646.     MOV    DX,CLOCK+VALID        ;PORT FOR VERIFY RAM
  647.     IN    AL,DX
  648.     CMP    AL,VALID_CODE        ;ARBITRARY VALIDATION CODE
  649.     JZ    FINE
  650. ;
  651. ;RESET CHIP, CAN'T TRUST IT
  652. ;
  653.     MOV    AL,0FFH         ;RESET ALL REGISTERS
  654.     MOV    DX,CLOCK+COUNTER_RESET    ;
  655.     OUT    DX,AL            ;RESET ALL COUNTERS
  656.     INC    DX            ;RAM(LATCH) RESET ADDR
  657.     OUT    DX,AL            ;NOW RESET RAM
  658.     MOV    AL,VALID_CODE
  659.     MOV    DX,CLOCK+VALID        ;NOW VALIDATE RAM
  660.     OUT    DX,AL
  661.  
  662. FINE:
  663. ;                                         dmo
  664. ;    now - initialize bios ram counter                     dmo
  665. ;                                         dmo
  666.     call    read_chip        ;time off chip                 dmo
  667.     call    set_bios_counter    ;setup bios timer             dmo
  668.  
  669.     STATUS    DONE,NOERROR,0
  670.     JMP    EXIT
  671.  
  672. CLK    ENDP
  673. CSEG    ENDS
  674.     END    BEGIN
  675. ounter    ;setup bios timer             dmo
  676.  
  677.     STATUS    DONE,NOERROR,0
  678.     JMP    EXIT
  679.  
  680. CLK    ENDP
  681. CSEG    ENDS
  682.     END    BEGIN
  683.